package freemap;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import nmap.nmapToFreemap;
import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

/**
 *
 * @author chris
 */
public class Freemap {

    private IdGenerator idGenerator = new IdGenerator();
    private Node rootNode;

    public Freemap() {
    }

    public Freemap(String rootNodeText) {
        rootNode = new Node(rootNodeText, idGenerator.getID());
    }

    public String getId() {
        return idGenerator.getID();
    }

    public void addNode(Node n) {
        rootNode.addChild(n);
    }

    public String createMap() {
        String output = "<map version=\"0.9.0\">\r\n";
        output += rootNode.toFreemindFormat();
        output += "</map>";
        return output;
    }

    public Node getRootNode() {
        return rootNode;
    }

    public void setRootNode(Node rootNode) {
        this.rootNode = rootNode;
    }

    public Freemap alternateNodes(Freemap map) {
        int x = 0;
        for (Node n : map.getRootNode().getChildren()) {
            x++;
            if (x % 2 == 0) {
                n.setPosition(Position.LEFT);
            } else {
                n.setPosition(Position.RIGHT);
            }
        }
        return map;
    }

    public Freemap xmlToFreemapTransformation(File f) {
        Freemap buildMindmap = null;
        try {
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(f);
            buildMindmap = buildMindmap(doc.getRootElement());

        } catch (JDOMException ex) {
            Logger.getLogger(nmapToFreemap.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(nmapToFreemap.class.getName()).log(Level.SEVERE, null, ex);
        }
        return buildMindmap;
    }

    private Freemap buildMindmap(Element root) {
        Freemap map = new Freemap(root.getName());
        Node n = map.getRootNode();
        List<Node> elementChildren = buildNodesFromChildren(root, map);
        n.getChildren().addAll(elementChildren);
        map.setRootNode(n);
        return map;
    }

    private List<Node> buildNodesFromAttributes(Element elem, Freemap map) {
        List<Node> result = new ArrayList<Node>();
        for (Attribute att : elem.getAttributes()) {
            Node n = new Node(att.getName() + " = " + att.getValue(), map.getId());
            result.add(n);
        }
        return result;
    }

    private List<Node> buildNodesFromChildren(Element elem, Freemap map) {
        List<Node> result = new ArrayList<Node>();
        int x = 0;
        for (Element e : elem.getChildren()) {
            Node n = new Node(e.getName(), map.getId());
            if (e.getChildren().size() > 0) {
                n.getChildren().addAll(buildNodesFromChildren(e, map));
            }
            n.getChildren().addAll(buildNodesFromAttributes(e, map));
            result.add(n);
        }
        return result;
    }

    private class IdGenerator {

        private List<Long> idList = new ArrayList<Long>();

        public IdGenerator() {
            idList.add(0l);
        }

        private String getID() {
            long maxId = idList.get(idList.size() - 1);
            String id = "ID_" + (maxId + 1);
            idList.add(maxId + 1);
            return id;
        }
    }
}